package org.example.groupwarehouse.service;

import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import jakarta.servlet.http.HttpSession;
import org.springframework.stereotype.Service;

import javax.imageio.ImageIO;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.IOException;
import java.util.Random;

/**
 * 验证码服务类
 * 用于生成和验证图形验证码
 */
@Service
public class CaptchaService {

    // 验证码图片的宽度
    private int width = 90;
    // 验证码图片的高度
    private int height = 40;
    // 验证码字符个数
    private int codeCount = 5;
    // 验证码干扰线数
    private int lineCount = 20;
    // 验证码在Session中的key
    private static final String CAPTCHA_KEY = "captcha";
    // 随机数生成器
    private Random random = new Random();
    // 可选字符
    private char[] codeSequence = {'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J',
            'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W',
            'X', 'Y', 'Z', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9'};

    /**
     * 生成验证码图片并输出到响应流
     *
     * @param request  HTTP请求
     * @param response HTTP响应
     * @throws IOException IO异常
     */
    public void generateCaptcha(HttpServletRequest request, HttpServletResponse response) throws IOException {
        // 设置响应的类型格式为图片格式
        response.setContentType("image/jpeg");
        // 禁止图像缓存
        response.setHeader("Pragma", "no-cache");
        response.setHeader("Cache-Control", "no-cache");
        response.setDateHeader("Expires", 0);

        // 创建BufferedImage对象，设置图片的长宽和色彩
        BufferedImage image = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
        // 获取图形上下文
        Graphics2D g = image.createGraphics();

        // 生成随机类
        Random random = new Random();

        // 设定背景色
        g.setColor(Color.WHITE);
        g.fillRect(0, 0, width, height);

        // 设定字体
        g.setFont(new Font("Times New Roman", Font.BOLD, 24));

        // 画边框
        g.setColor(Color.BLACK);
        g.drawRect(0, 0, width - 1, height - 1);

        // 随机产生干扰线，使图像中的认证码不易被其它程序探测到
        g.setColor(Color.GRAY);
        for (int i = 0; i < lineCount; i++) {
            int x = random.nextInt(width);
            int y = random.nextInt(height);
            int xl = random.nextInt(12);
            int yl = random.nextInt(12);
            g.drawLine(x, y, x + xl, y + yl);
        }

        // 保存验证码
        StringBuilder randomCode = new StringBuilder();

        // 随机产生验证码字符
        for (int i = 0; i < codeCount; i++) {
            // 得到随机产生的验证码数字
            String strRand = String.valueOf(codeSequence[random.nextInt(codeSequence.length)]);
            // 产生随机的颜色
            g.setColor(new Color(random.nextInt(255), random.nextInt(255), random.nextInt(255)));
            // 在图片上画验证码
            g.drawString(strRand, 15 * i + 10, 30);
            // 将产生的四个随机数组合在一起
            randomCode.append(strRand);
        }

        // 将验证码存入Session
        System.out.println(randomCode);
        HttpSession session = request.getSession();
        session.setAttribute(CAPTCHA_KEY, randomCode.toString());

        // 释放图形上下文
        g.dispose();

        // 将图像输出到响应输出流中
        ImageIO.write(image, "JPEG", response.getOutputStream());
        response.getOutputStream().flush();
    }

    /**
     * 验证输入的验证码是否正确
     *
     * @param session      HTTP会话
     * @param inputCaptcha 用户输入的验证码
     * @return 验证结果
     */
    public boolean validateCaptcha(HttpSession session, String inputCaptcha) {
        // 获取Session中的验证码
        String captcha = (String) session.getAttribute(CAPTCHA_KEY);
        // 验证码使用后立即清除，防止重复使用
        session.removeAttribute(CAPTCHA_KEY);
        
        // 验证码为空或不匹配
        if (captcha == null || inputCaptcha == null) {
            return false;
        }
        
        // 不区分大小写比较
        return captcha.equalsIgnoreCase(inputCaptcha);
    }
} 